package com.csw.compose.ui.module.component.advanced

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableIntState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.csw.compose.theme.AppTheme
import com.csw.compose.theme.pagePadding
import com.csw.compose.ui.Destination
import com.csw.compose.ui.components.BodyText
import com.csw.compose.ui.components.LabelText
import com.csw.compose.ui.components.LargeSpacer
import com.csw.compose.ui.components.LeftTitleWithBack
import com.csw.compose.ui.components.NormalSpacer
import com.csw.compose.ui.components.OlItem
import com.csw.compose.ui.components.PrimaryTitle
import com.csw.compose.ui.components.UlItem
import com.csw.compose.ui.getDataObject
import com.csw.compose.ui.module.BasePage

@Preview
@Composable
fun NavigationPreview() {
    BasePage(
        {},
        "页面导航"
    ) { NavigationPage { HomePage(remember { mutableIntStateOf(1) }, {}, {}) } }
}

@Preview
@Composable
fun JumpPagePreview() {
    AppTheme {
        JumpPage {}
    }
}

@Preview
@Composable
fun ParamsPagePreview() {
    AppTheme {
        ParamsPage(ParamsData(1)) {}
    }
}

class NavigationData {
    companion object : Destination("Navigation")
}

/**
 * [参考](https://developer.android.google.cn/codelabs/jetpack-compose-navigation?hl=zh_cn#0)
 */
@Composable
fun NavigationPage(example: @Composable () -> Unit = { ExampleNavHost() }) {
    Column(
        modifier = Modifier
            .padding(horizontal = pagePadding)
            .verticalScroll(rememberScrollState())
    ) {
        PrimaryTitle("简介")
        BodyText("Compose Navigation提供了与Flutter类似的路由跳转，将路径与页面一一对应，这样即可通过navigation跳转对应路径的页面")
        UlItem("NavHost")
        LabelText("导航容器，所有页面将在容器中切换，其添加了页面切换的转场效果与返回处理")
        NormalSpacer()
        OlItem(1, "NavHostController")
        LabelText("导航控制器，通过rememberNavController()创建实例，可以控制页面跳转")
        BodyText("- navigate(route)跳转页面")

        OlItem(2, "startDestination")
        LabelText("初始化目的地，Navigation通过route标记，此外还有转场效果等设置")

        OlItem(3, "composable(route,arguments){}")
        LabelText("通过此组件添加页面")
        BodyText("- route参数用于指定页面的路由地址，该地址为签名，若页面有参数需要在地址中添加占位符")
        LabelText("    name/p1/p2?p3={p3}&p4={p4}，类似url，必传参数添加到路径中以/分割，可选参数以类似GET请求的方式拼接，即以?开头&分割。")
        LabelText("    通过navigate页面跳转时，替换相应的占位符进行赋值。")
        BodyText("- arguments参数用于指定页面传参")
        LabelText("    通过这个属性设置每个参数的类型、是否可空、是否有默认值，在navigate跳转时，框架会检查参数")
        LabelText("    但由于其使用麻烦，参杂很多常量定义，读参也麻烦，本应用中使用时做了优化，传参一律以data为key将数据类对象转为json字符串进行传输，简化Navigation的使用")
        LabelText("    数据类的定义也可以很清晰的做到参数可空、默认值设置")

        LargeSpacer()
        PrimaryTitle("示例")
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .height(300.dp)
        ) {
            example()
        }
    }
}

@Composable
fun ExampleNavHost() {
    val navController = rememberNavController()
    val number = remember { mutableIntStateOf(100) }
    NavHost(
        navController, HomeData.route, modifier = Modifier
            .fillMaxSize()
            .padding(10.dp)
    ) {
        composable(HomeData.route) {
            HomePage(number, { navController.navigate(JumpData.getRouteWithParams()) }, {
                navController.navigate(
                    ParamsData.getRouteWithParams(ParamsData(number.intValue))
                )
            })
        }
        composable(JumpData.route) {
            JumpPage(navController::popBackStack)
        }
        composable(ParamsData.route) {
            ParamsPage(it.arguments?.getDataObject()) { newValue ->
                navController.popBackStack()
                number.intValue = newValue
            }
        }
    }
}

class HomeData {
    companion object : Destination("HomePage")
}

@Composable
fun HomePage(number: MutableIntState, openJump: () -> Unit, openParams: () -> Unit) {
    Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
        Button(openJump) { Text("简单的页面跳转") }
        Button(openParams) {
            Text(
                "传参并返回（${number.intValue}）"
            )
        }
    }
}

class JumpData {
    companion object : Destination("TestJump")
}

@Composable
fun JumpPage(onClickBack: () -> Unit) {
    Scaffold(
        topBar = {
            LeftTitleWithBack("Test Jump", onClickBack = onClickBack)
        },
    ) {
        Box(modifier = Modifier.padding(it)) {}
    }
    BasePage(onClickBack, "Test Jump") {}
}

class ParamsData(val value: Int? = 0) {
    companion object : Destination("TestParams")
}

@Composable
fun ParamsPage(
    data: ParamsData?, onClickBack: (Int) -> Unit
) {
    val number = remember { mutableIntStateOf(data?.value ?: 0) }
    BasePage({ onClickBack(number.intValue) }, "Test Params") {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.Center
        ) {
            Button({ number.intValue-- }) { Text("-") }
            Text("${number.intValue}")
            Button({ number.intValue++ }) { Text("+") }
        }
    }
}
